package com.deruan.hotcore.resource.table.model;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import javax.swing.event.ChangeEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.TableColumnModelEvent;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;

import org.columba.mail.gui.table.model.MessageNode;
import org.columba.mail.gui.table.model.ModelVisitor;
import org.frapuccino.treetable.AbstractTreeTableModel;

import com.deruan.hotcore.base.common.bean.ResourceBean;
import com.deruan.hotcore.resource.gui.tree.ResourceTreeNode;

public class ResourceHeaderTableModel extends AbstractTreeTableModel implements IResourceHeaderTableModel
{
	/**
	 * list of column IDs
	 */
	private List columns = new Vector();
	protected List<ResourceBean> resourceList;
	protected Map map = new HashMap();
	private ResourceTreeNode root;
	private Vector visitors = new Vector();
	
	public ResourceHeaderTableModel()
	{
		
	}
	
	public ResourceHeaderTableModel(String[] c)
	{
        //add array to vector
		for (int i = 0; i < c.length; i++) 
		{
			columns.add(c[i]);
		}
	}
	
	public void registerVisitor(ResourceModelVisitor visitor) {
		visitors.add(visitor);
	}
	
	public void modify(Object[] uids) 
	{}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.columba.mail.gui.table.model.TableModelModifier#remove(java.lang.Object[])
	 */
	public void remove(Object[] uids) 
	{
		if (uids != null) {
			for (int i = 0; i < uids.length; i++) {
				ResourceTreeNode node = (ResourceTreeNode) map.get(uids[i]);

				if (node != null) {
					map.remove(node);

					if (node.getParent() != null) {
						getTreeModel().removeNodeFromParent(node);
					}
				}
			}

		}
	}

	public void reset() 
	{
		if (root == null) 
		{
			root = new ResourceTreeNode(new ResourceBean());
			tree.setRootNode(root);		
	    }

		// remove all children from tree
		root.removeAllChildren();
		// clear messagenode cache
		map.clear();
		
		if ((resourceList == null) || (resourceList.size() == 0)) 
		{
			// table is empty
			// -> just display empty table			
			getTreeModel().nodeStructureChanged(getRootNode());		
			fireTableDataChanged();
			return;
		}	
	}
	
	public void update() {
		if ((resourceList == null) || (resourceList.size() == 0)) {
			// table is empty
			// -> just display empty table			
			root.removeAllChildren();
			
			getTreeModel().nodeStructureChanged(getRootNode());
			
			fireTableDataChanged();
			
			return;
		}
		
		// add every header from HeaderList to the table as MessageNode
		for (Iterator<ResourceBean> it = resourceList.iterator(); it.hasNext();) 
		{
			// get unique id
			ResourceBean bean = it.next();		
			if( !map.containsKey(bean.getId())) 
			{
				// create MessageNode
				ResourceTreeNode child = new ResourceTreeNode(bean);
				// add this node to cache
				map.put(bean.getId(), child);
				// add node to tree
				root.add(child);
			}
		}	
		getTreeModel().nodeStructureChanged(getRootNode());
		
		fireTableDataChanged();
	}
	
	public void clear() 
	{
		root = new ResourceTreeNode(new ResourceBean());
		tree.setRootNode(root);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.columba.mail.gui.table.model.TableModelModifier#set(org.columba.mail.message.HeaderList)
	 */
	public void set(List<ResourceBean> resourceList) {
		this.resourceList = resourceList;
		reset();
		update();
	}

	public ResourceTreeNode getRootNode()
	{
		return root;
	}

	public List<ResourceBean> getHeaderList() {
		return resourceList;
	}

	public ResourceTreeNode getMessageNode(Object uid) {
		return (ResourceTreeNode) map.get(uid);
	}

	public DefaultTreeModel getTreeModel() {
		return (DefaultTreeModel) getTree().getModel();
	}

	/** ******************* AbstractTableModel implementation ******************* */
	public int getColumnCount() {
		return columns.size();
	}

	public int getRowCount() {
		if (getTree() != null) {
			return getTree().getRowCount();
		} else {
			return 0;
		}
	}

	public Object getValueAt(int row, int col) {
		//if ( col == 0 ) return tree;
		TreePath treePath = getTree().getPathForRow(row);
		if( treePath == null) return null;
		
		return (ResourceTreeNode) treePath.getLastPathComponent();
	}

	/**
	 * Get row for node.
	 * 
	 * @param node
	 *            selected message node
	 * @return current row of node
	 */
	public int getRow(MessageNode node) {

		for (int i = 0; i < getTree().getRowCount(); i++) {
			MessageNode n = (MessageNode) getValueAt(i, 0);
			if (n.getUid().equals(node.getUid()))
				return i;
		}

		return -1;
	}

	public String getColumnName(int column) {
		return (String) columns.get(column);
	}

	public int getColumnNumber(String name) {
		for (int i = 0; i < getColumnCount(); i++) {
			if (name.equals(getColumnName(i))) {
				return i;
			}
		}

		return -1;
	}

	/**
	 * Get the class which is responsible for renderering this column.
	 * <p>
	 * If the threaded-view is enabled, return a custom tree cell renderer.
	 * <p>
	 * 
	 * @see org.columba.mail.gui.table.TableView#enableThreadedView
	 */
	public Class getColumnClass(int column) 
	{
		return getValueAt(0, column).getClass();
	}

	public boolean isCellEditable(int row, int col) {
		String name = getColumnName(col);

		if (name.equalsIgnoreCase("Subject")) {
			return true;
		}

		return false;
	}

	/**
	 * Set column IDs
	 * 
	 * @param c
	 *            array of column IDs
	 */
	public void setColumns(String[] c) {
		columns = new Vector();

		// add array to vector
		for (int i = 0; i < c.length; i++) {
			columns.add(c[i]);
		}
	}

	/**
	 * Add column to table model.
	 * 
	 * @param c
	 *            new column ID
	 */
	public void addColumn(String c) {
		columns.add(c);
	}

	/**
	 * Clear column list.
	 *  
	 */
	public void clearColumns() {
		columns.clear();
	}

	/**
	 * @see org.columba.mail.gui.table.IHeaderTableModel#getMessageNodeAtRow(int)
	 */
	public ResourceTreeNode getMessageNodeAtRow(int index) {
		return (ResourceTreeNode) getValueAt(index,0);
	}

	public void columnMarginChanged(ChangeEvent e) {
	}

	public void columnSelectionChanged(ListSelectionEvent e) {
	}

	public void columnAdded(TableColumnModelEvent e) {
	}

	public void columnMoved(TableColumnModelEvent e) {
		if( e.getFromIndex() != e.getToIndex()) {
			columns.add(e.getToIndex(),columns.remove(e.getFromIndex()));
		}
	}

	public void columnRemoved(TableColumnModelEvent e) {
	}
}
